home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Format / rfc934 / do-rfc934.c next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  12.3 KB  |  586 lines

  1. /* do-rfc934.c: routines to carry out rfc934 conversion */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Format/rfc934/RCS/do-rfc934.c,v 6.0 1991/12/18 20:21:02 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Format/rfc934/RCS/do-rfc934.c,v 6.0 1991/12/18 20:21:02 jpo Rel $
  9.  *
  10.  * $Log: do-rfc934.c,v $
  11.  * Revision 6.0  1991/12/18  20:21:02  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include    "util.h"
  19. #include    <sys/stat.h>
  20. #include    <fcntl.h>
  21. #include    <isode/usr.dirent.h>
  22. #include    "retcode.h"
  23. #include    <isode/cmd_srch.h>
  24. #include    "tb_bpt84.h"
  25.  
  26.  
  27. extern CMD_TABLE bptbl_body_parts84[/* x400 84 body_parts */];
  28. extern char *hdr_822_bp;
  29.  
  30. #define EBch    '-'
  31. #define Stuffing "- "
  32.  
  33. char    file[MAXPATHLENGTH],
  34.     line[LINESIZE];
  35. int    fp;
  36. int     more = TRUE;
  37. int    start_depth = 0;
  38. /* number of chars in buffer currently */
  39. int     noInput = 0;
  40. int    err_fatal = FALSE;
  41.  
  42. static int recursiveproc();
  43. static int ishdr();
  44. static int file_link();
  45. static void output_startmessage();
  46. static void output_endmessage();
  47. static int depth();
  48. static void output_stuffing();
  49. static void output_endbodypart();
  50. static void output_line();
  51. static int  output_file();
  52. static int output_header();
  53. static void output_ia5();
  54. static int numBodyParts();
  55. static int bpFile();
  56. #define MaxCharPerInt 16
  57.  
  58. static char    *itoa(i)
  59. int     i;
  60. {
  61.     char     buf[MaxCharPerInt];
  62.  
  63.     sprintf(buf,"%d",i);
  64.     
  65.     return strdup(buf);
  66.     
  67. }
  68.  
  69. int do_rfc934(from,to,perr)
  70. char    *from,    /* original directory */
  71.     *to,    /* new directory */
  72.     **perr;
  73. {
  74.     char    hdr[MAXPATHLENGTH],
  75.         *stripped_hdr,
  76.         outfile[MAXPATHLENGTH],
  77.         buf[BUFSIZ],
  78.         wrkfile[MAXPATHLENGTH];
  79.     int    result = OK,
  80.         msgnum = 1,
  81.         fd_in,
  82.         first,
  83.         noBps,
  84.         bodynum;
  85.     noInput = 0;
  86.     msg_rinit(from);
  87.     start_depth = depth(from) + 1;
  88.     err_fatal = FALSE;
  89.  
  90.     noBps = numBodyParts(from);
  91.  
  92.     if (msg_rfile(hdr) != RP_OK) {
  93.         PP_LOG(LLOG_EXCEPTIONS,
  94.             ("Chans/rfc934 directory '%s' is empty",from));
  95.         (void) sprintf (buf,
  96.                 "directory '%s' is empty",
  97.                 from);
  98.         *perr = strdup(buf);
  99.         return NOTOK;
  100.     }
  101.     if ((stripped_hdr = rindex(hdr,'/')) == NULL)
  102.         stripped_hdr = hdr;
  103.     else
  104.         stripped_hdr++;
  105.  
  106.     if (ishdr(stripped_hdr) != OK) {
  107.         PP_LOG(LLOG_EXCEPTIONS,
  108.             ("Chans/rfc934 cannot find hdr in '%s'",hdr));
  109.         (void) sprintf (buf,
  110.                 "Did not find valid header in message - unable to flatten");
  111.         err_fatal = TRUE;
  112.         *perr = strdup(buf);
  113.         return NOTOK;
  114.     } 
  115.  
  116.     if (result != OK)
  117.         return NOTOK;
  118.     if (msg_rfile(file) != RP_OK) {
  119.         /* empty body that's ok */
  120.         result = file_link(from,to,
  121.                    stripped_hdr);
  122.         return OK;
  123.     }
  124.  
  125.     more = TRUE;
  126.     first = TRUE;
  127.  
  128.     do {
  129.         if (depth(file) > start_depth) {
  130.             if (first == TRUE) {
  131.                 result = put_out_header(hdr, to, stripped_hdr);
  132.                 /* open output file */
  133.                 sprintf(outfile,"%s/1.ia5",to);
  134.                 if ((fp = open(outfile, 
  135.                            O_WRONLY | O_CREAT | O_TRUNC, 
  136.                            0666)) == -1) {
  137.                     PP_SLOG(LLOG_EXCEPTIONS, outfile,
  138.                         ("Can't open file"));
  139.                     (void) sprintf(buf,
  140.                                "Unable to open output file '%s'",
  141.                                outfile);
  142.                     *perr = strdup(buf);
  143.                     return NOTOK;
  144.                 }
  145.             }
  146.             result = recursiveproc(msgnum++,perr);
  147.         } else {
  148.             strcpy(wrkfile, file);
  149.             if (msg_rfile(file) != RP_OK)
  150.                 more = FALSE;
  151.             if (first == TRUE) {
  152.                 if (more == FALSE) {
  153.                     /* single body part */
  154.                     /* link hdr across */
  155.                     result = file_link(from,to,
  156.                                stripped_hdr);
  157.                     /* link single body part across */
  158.                     result = file_link(from, to, 
  159.                                rindex(wrkfile,'/'));
  160.                     return result;
  161.                 } else {
  162.                     put_out_header(hdr, to, stripped_hdr);
  163.                     /* open output file */
  164.                     sprintf(outfile,"%s/1.ia5",to);
  165.                     if ((fp = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) {
  166.                         PP_SLOG(LLOG_EXCEPTIONS, outfile,
  167.                             ("Can't open file"));
  168.                         (void) sprintf(buf,
  169.                                    "Unable to open output file '%s'",
  170.                                    outfile);
  171.                         *perr = strdup(buf);
  172.                         return NOTOK;
  173.                     }
  174.                     
  175.                 }
  176.             }
  177.  
  178.             if ((fd_in = open(wrkfile, O_RDONLY)) == -1) {
  179.                 PP_SLOG(LLOG_EXCEPTIONS, wrkfile,
  180.                     ("Can't open file"));
  181.                 (void) sprintf (buf,
  182.                         "Unable to open input file '%s'",
  183.                         wrkfile);
  184.                 *perr = strdup(buf);
  185.                 result = NOTOK;
  186.             }
  187.             if (result == OK) {
  188.                 result = output_file(fd_in,start_depth,wrkfile, noBps, &bodynum, perr);
  189.                 if (more == FALSE) 
  190.                     output_endbodypart(fp,  bodynum, start_depth);
  191.                 close(fd_in);
  192.             }
  193.         }
  194.         first = FALSE;
  195.     } while (result == OK && more == TRUE);
  196.     close(fp);
  197.     return result;
  198. }
  199.  
  200. static int recursiveproc(num, perr)
  201. int    num;
  202. char    **perr;
  203. /* uses external file */
  204. {
  205.     int     mydepth;
  206.     int    fd_in;
  207.     int    result = OK;
  208.     int    bpnum, bodynum = 0;
  209.     char    *dir_stub = NULL, buf[BUFSIZ],
  210.         *ix;
  211.     int    cont,
  212.         msgnum = 1;
  213.     int    noBps;
  214.  
  215.     mydepth = depth(file);
  216.     if ((ix = rindex(file,'/')) == NULL) 
  217.         dir_stub = strdup(file);
  218.     else{
  219.         while (*(ix-1) == '/')
  220.             ix--;
  221.         *ix = '\0';
  222.         dir_stub = strdup(file);
  223.         *ix = '/';
  224.     }
  225.     if ((ix = rindex(dir_stub, '/')) == NULL)
  226.         ix = dir_stub;
  227.     else
  228.         ix++;
  229.     bpnum = atoi(ix);
  230.     noBps = numBodyParts(dir_stub);
  231.  
  232.     output_startmessage(fp,num,bpnum,mydepth);
  233.     do {
  234.         /* output file with char stuffing */
  235.         if ((fd_in = open(file, O_RDONLY)) == -1) {
  236.             PP_SLOG(LLOG_EXCEPTIONS, file,
  237.                 ("Can't open file"));
  238.             (void) sprintf(buf,
  239.                        "Unable to open input file '%s'",
  240.                        file);
  241.             result = NOTOK;
  242.         }
  243.         if (result == OK) {
  244.             result = output_file(fd_in,mydepth,file,noBps,
  245.                          &bodynum,perr);
  246.             close(fd_in);
  247.         }
  248.  
  249.         if (msg_rfile(file) != RP_OK)
  250.             more = FALSE;
  251.         else {
  252.             if (depth(file) > mydepth)
  253.                 result = recursiveproc(msgnum++,perr);
  254.             bodynum = 0;
  255.         }
  256.         cont = FALSE;
  257.         if ((result == OK) 
  258.             && (more == TRUE) 
  259.             && (depth(file) == mydepth))
  260.             cont = TRUE;
  261.         if ((ix = rindex(file,'/')) != NULL) {
  262.             while (*(ix-1) == '/')
  263.                 ix--;
  264.             *ix = '\0';
  265.         }
  266.         if ((cont == TRUE)
  267.             && (strcmp(dir_stub,file) != 0))
  268.             cont = FALSE;
  269.         if (ix != NULL)
  270.             *ix = '/';
  271.     } while ((result == OK) && (more == TRUE) && (cont == TRUE));
  272.     if (dir_stub != NULL) free(dir_stub);
  273.     if (noBps > 1 && bodynum != 0)
  274.         output_endbodypart(fp, bodynum, mydepth);
  275.     output_endmessage(fp,num,bpnum,mydepth);
  276.     return result;
  277. }
  278.  
  279. static int ishdr(name)
  280. char    *name;
  281. {
  282.  
  283. /*    if (strcmp(name,rcmd_srch(BPT_HDR_P2,bptbl_body_parts84)) == 0)
  284.         return OK;
  285.     if (strcmp(name,rcmd_srch(BPT_HDR_822,bptbl_body_parts84)) == 0)
  286.         return OK;*/
  287.     if (strncmp(name,hdr_822_bp,strlen(hdr_822_bp)) == 0)
  288.         return OK;
  289.     return NOTOK;
  290. }
  291.  
  292. /*   */
  293. /* input and output routines */
  294. #define    CMASK    0377 /* for making char's > 0 */
  295.  
  296. #define    Start_message "------------------------------ Start of forwarded message "
  297.  
  298. static void output_startmessage(fd, num, bpnum, deep)
  299. int    fd;
  300. int    num;
  301. int    bpnum;
  302. int    deep;
  303. {
  304.     char    *cnum = itoa(num);
  305.     if (bpnum != 1)
  306.         write(fd,"\n",strlen("\n"));
  307.     output_stuffing(fd,deep-1);
  308.     write(fd,Start_message,strlen(Start_message));
  309.     write(fd,cnum,strlen(cnum));
  310.     free(cnum);
  311. /*    write(fd," (bodypart ",strlen("(bodypart "));
  312.     cnum = itoa(bpnum);
  313.     write(fd,cnum,strlen(cnum));*/
  314.     write(fd,"\n\n",strlen("\n\n"));
  315.     free(cnum);
  316. }
  317.  
  318. #define End_message "------------------------------ End of forwarded message "
  319.  
  320. static void output_endmessage(fd,num,bpnum,deep)
  321. int    fd,
  322.     num,
  323.     bpnum,
  324.     deep;
  325. {
  326.     char    *cnum = itoa(num);
  327.     write(fd,"\n",strlen("\n"));
  328.     output_stuffing(fd,deep-1);
  329.     write(fd,End_message,strlen(End_message));
  330.     write(fd,cnum,strlen(cnum));
  331.     free(cnum);
  332. /*    write(fd," (bodypart ",strlen("(bodypart "));
  333.     cnum = itoa(bpnum);
  334.     write(fd,cnum,strlen(cnum));*/
  335.     if (more == FALSE) 
  336.         write(fd,"\n",strlen("\n"));
  337.     else
  338.         write(fd,"\n\n",strlen("\n\n"));
  339.     free(cnum);
  340. }
  341.  
  342. #define Bodypart_seperatorstart "------------------------------ Start of body part "
  343. #define Bodypart_seperatorend "------------------------------ End of body part "
  344.  
  345. static int output_startbodypart(fd, num, deep)
  346. int    fd;
  347. int    num;
  348. int    deep;
  349. {
  350.     char    *cnum = itoa(num);
  351.     write(fd,"\n",strlen("\n"));
  352.     output_stuffing(fd,deep);
  353.     write(fd,Bodypart_seperatorstart,strlen(Bodypart_seperatorstart));
  354.     write(fd,cnum,strlen(cnum));
  355.     write(fd,"\n\n",strlen("\n\n"));
  356.     free(cnum);
  357. }
  358.  
  359. static void output_endbodypart(fd, num, deep)
  360. int    fd;
  361. int    num;
  362. int     deep;
  363. {
  364.     char    *cnum = itoa(num);
  365.  
  366.     write(fd,"\n",strlen("\n"));
  367.     output_stuffing(fd,deep);
  368.     write(fd,Bodypart_seperatorend,strlen(Bodypart_seperatorend));
  369.     write(fd,cnum,strlen(cnum)); 
  370.     if (more == FALSE)
  371.         write(fd,"\n",strlen("\n"));
  372.     else
  373.         write(fd,"\n\n",strlen("\n\n"));
  374.     free(cnum);
  375. }
  376.  
  377.  
  378. static int mygetchar(fd)
  379. int    fd;
  380. {
  381.     static unsigned char    buf[MAXPATHLENGTH];
  382.     static unsigned char    *bufp = buf;
  383.  
  384.     if (noInput == 0) { /* buffer is empty */
  385.         noInput = read(fd, buf, MAXPATHLENGTH);
  386.         bufp = buf;
  387.     }
  388.     return ((--noInput >= 0) ? *bufp++ : EOF);
  389. }
  390.  
  391. static int getline(fd,linebuf)
  392. int    fd;
  393. char    linebuf[];
  394. {
  395.     int     i = 0;
  396.     int     c;
  397.     while (i < LINESIZE && ((c = mygetchar(fd)) != EOF) && c != '\n')
  398.            linebuf[i++] = c;
  399.     if (c == '\n')
  400.         linebuf[i++] = c;
  401.     linebuf[i] = '\0';
  402.     return i;
  403. }
  404.  
  405. static void output_stuffing(fd, deep)
  406. int    fd;
  407. int    deep;
  408. {
  409.     int i = 0;
  410.     while (i++ < (deep - start_depth))
  411.         write(fd,Stuffing,strlen(Stuffing));
  412. }
  413.  
  414. static void output_line(fd,buf)
  415. int    fd;
  416. char    buf[];
  417. {
  418.     write(fd,buf,strlen(buf));
  419. }
  420.  
  421. static int output_file(fd_in, deep, filename, noBps,pnum, perr)
  422. int    fd_in,    
  423.     deep;
  424. char    *filename;
  425. int    noBps;
  426. int    *pnum;
  427. char    **perr;
  428. {
  429.     char    *ix = NULL, buf[BUFSIZ],
  430.         *ix2;
  431.     /* reset input buffer */
  432.     noInput = 0;
  433.     
  434.     if (((ix = rindex(filename,'/')) != NULL)
  435.         && (strncmp(++ix, hdr_822_bp, strlen(hdr_822_bp)) == 0)) {
  436.         output_header(fd_in, FALSE);
  437.         output_line(fp, "\n");
  438.         return OK;
  439.     } else if (strcmp(ix,rcmd_srch(BPT_P2_DLIV_TXT, bptbl_body_parts84)) == 0) {
  440.         PP_LOG(LLOG_EXCEPTIONS,
  441.                ("Chans/rfc934 : illegal file type '%s' ignoring it",filename));
  442.         return OK;
  443.     }
  444.  
  445.     if (((ix = rindex(filename,'.')) != NULL) &&
  446.         (strcmp(++ix, rcmd_srch(BPT_IA5, bptbl_body_parts84)) == 0)) {
  447.         *(ix - 1) = '\0';
  448.         ix2 = rindex(filename,'/');
  449.         *ix2++ = '\0';
  450.         *pnum = atoi(ix2);
  451.         output_ia5(fd_in, deep, *pnum, noBps);
  452.         *(ix - 1) = '.';
  453.         *(ix2 - 1) ='/';
  454.         return OK;
  455.     }
  456.     
  457.     PP_LOG(LLOG_EXCEPTIONS,
  458.            ("Chans/rfc934 : illegal file type '%s' BOMBING OUT",filename));
  459.     (void) sprintf(buf,
  460.                "illegal file type '%s' unable to flatten",
  461.                filename);
  462.     *perr = strdup(buf);
  463.     err_fatal = TRUE;
  464.     return NOTOK;
  465. }
  466.  
  467. static int output_header(fd_in, first)
  468. int    fd_in;
  469. int    first;
  470. {
  471.     int    msgtype;
  472.  
  473.     msgtype = FALSE;
  474.     while(getline(fd_in,line) != 0) { 
  475.         if (first == TRUE
  476.             && line[0] == '\n'
  477.             && msgtype == FALSE)
  478.             output_line(fp, "Message-Type: Multiple Part");
  479.         output_line(fp, line);
  480.         if (strncmp(line, "Message-Type", strlen("Message-Type")) == 0)
  481.             msgtype = TRUE;
  482.     }
  483.     return msgtype;
  484. }
  485.  
  486. static void output_ia5(fd_in, deep, bp_num, noBps)
  487. int    fd_in,
  488.     deep,
  489.     bp_num,
  490.     noBps;
  491. {
  492.     if (noBps > 1)
  493.         output_startbodypart(fp, bp_num, deep);
  494.     while (getline(fd_in,line) != 0) {
  495.         if (line[0] == EBch)
  496.             output_stuffing(fp, deep);
  497.         output_line(fp, line);
  498.     }
  499. }
  500.  
  501.  
  502. static int depth (filename)
  503. char    *filename;
  504. {
  505.     char    *p;
  506.     int     count = 0;
  507.  
  508.     for (p = filename; *p; p++)
  509.         if (*p == '/') {
  510.             count ++;
  511.             while(*p == '/') p++;
  512.         }
  513.     return count;
  514. }
  515.  
  516. static int file_link(orig,tmp,filename)
  517. char    *orig,    /* original message directory */
  518.     *tmp,    /* new temporary directory */
  519.     *filename;    /* file to link across */
  520. {
  521.     char    old[MAXPATHLENGTH],    /* old file */
  522.             new[MAXPATHLENGTH];    /* new link */
  523.     struct stat statbuf;
  524.     int    result = OK;
  525.  
  526.     (void) sprintf(old, "%s/%s",orig,filename);
  527.  
  528.     (void) sprintf(new, "%s/%s",tmp,filename);
  529.  
  530.     if ((stat(old, &statbuf) == OK)
  531.         && (stat(new, &statbuf) != OK)
  532.         && (link(old, new) != -1)) {
  533.         result = OK;
  534.     } else
  535.         result = NOTOK;
  536.  
  537.     return result;
  538. }
  539.  
  540. put_out_header(old, to, stripped_hdr)
  541. char    *old,
  542.     *to,
  543.     *stripped_hdr;
  544. {
  545.     int    fd_in;
  546.     char    outfile[MAXPATHLENGTH];
  547.     int    gotMsgType = FALSE;
  548.     if ((fd_in = open(old, O_RDONLY)) == -1) {
  549.         PP_SLOG(LLOG_EXCEPTIONS, old,
  550.             ("Can't open file"));
  551.         return NOTOK;
  552.     }
  553.                     
  554.     sprintf(outfile,"%s/%s",to, stripped_hdr);
  555.     if ((fp = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) {
  556.         PP_SLOG(LLOG_EXCEPTIONS, outfile,
  557.             ("Can't open file"));
  558.         return NOTOK;
  559.     }
  560.     gotMsgType = output_header(fd_in, TRUE);
  561.     close(fd_in);
  562.     close(fp);
  563.     return OK;
  564. }
  565.  
  566. static int    bpFile(entry)
  567. struct dirent *entry;
  568. {
  569.     if (strcmp(entry->d_name, "..") == 0
  570.          || strcmp(entry->d_name, ".") == 0
  571.          || strncmp(entry->d_name, hdr_822_bp, strlen(hdr_822_bp)) == 0)
  572.         return 0;
  573.     return 1;
  574. }
  575.         
  576. static int numBodyParts(dir)
  577. char    *dir;
  578. {
  579.     struct dirent    **namelist = NULL;
  580.  
  581.     int ret = _scandir(dir, &namelist, bpFile, NULLIFP);
  582.  
  583.     if (namelist) free ((char *) namelist);
  584.     return ret;
  585. }
  586.